<template>
  <a-input-number
    v-if="type == 'number' && !showConfig.rangeNumber"
    :placeholder="placeholder"
    :value="getValue"
    @change="onChange"
    style="width: 100%"
    :min="min"
    :max="max"
    :step="step"
    :allowClear="true"
  />

  <!-- 范围数字-->
  <range-number
    v-else-if="type == 'number' && showConfig.rangeNumber"
    :placeholder="rangeNumberPlaceholder"
    :value="getValue"
    @change="onChange"
    style="width:100%"
    :min="min"
    :max="max"
    :step="step"
    :allowClear="true"
  />

  <a-select
    v-else-if="type=='select'"
    :value="getValue"
    :mode="multiple ? 'multiple' : ''"
    @change="onChange"
    :placeholder="placeholder"
    :allowClear="clearable"
    :showSearch="showConfig.showSearch"
    :filter-option="filterOption"
    :getPopupContainer="
      triggerNode => {
        return triggerNode.parentNode || document.body;
      }
    "
  >
    <a-select-option v-for="(item,index) in optionsResult" :key="index" :value="item.value" :title="item.text || item.label">
      {{ item.text || item.label}}
    </a-select-option>
  </a-select>

  <!-- 月份选择 -->
  <a-month-picker
    v-else-if="type == 'date' && dateFormat == 'YYYY-MM' && !showConfig.range"
    :placeholder="placeholder"
    :value="getValue"
    :allowClear="true"
    style="width:100%"
    :format="dateFormat"
    @change="onChange"
  />

  <!--日期选择-->
  <a-date-picker
    v-else-if="type == 'date' && !showConfig.range"
    :placeholder="placeholder"
    :value="getValue"
    :allowClear="true"
    style="width:100%"
    :show-time="!!showConfig.showTime"
    :format="dateFormat"
    @change="onChange"
  />

  <!-- 范围日期选择 -->
  <a-range-picker
    v-else-if="type == 'date' && showConfig.range"
    :placeholder="rangePlaceholder"
    :value="getValue"
    :allowClear="true"
    style="width:100%"
    :show-time="!!showConfig.showTime"
    :format="dateFormat"
    @change="onChange"
  />

  <!-- 时间选择 -->
  <a-time-picker
    v-else-if="type == 'time'"
    :placeholder="placeholder"
    :value="getValue"
    :allowClear="true"
    style="width:100%"
    :format="timeFormat"
    @change="onChange"
  />
  <!-- 用户选择 -->
  <ych-select-user
    v-else-if="type == 'user'"
    :placeholder="placeholder"
    :value="getValue"
    :multi="multiple"
    :customReturnField="useCode ? 'username' : 'id'"
    :customOrgOrderSql="customOrgOrderSql"
    :customOrgFilterSql="customOrgFilterSql"
    :linkage="linkage"
    :linkageMap="linkageMap"
    @change="onChange"
  />
  <!-- 部门选择 -->
  <ych-select-depart
    v-else-if="type == 'dept'"
    :placeholder="placeholder"
    :value="getValue"
    :multi="multiple"
    :customReturnField="useCode ? 'orgCode' : 'id'"
    :customOrgOrderSql="customOrgOrderSql"
    :customOrgFilterSql="customOrgFilterSql"
    @change="onChange"
  />
  <!-- 开关 -->
  <a-switch
    v-else-if="type == 'switch'"
    @change="onChangeSwitch"
    :checked="getValue"
  />
  <a-input
    v-else
    :placeholder="placeholder"
    :value="getValue"
    :allowClear="true"
    @change="onChangeInput"
    @blur="onChangeBlur"
  />

</template>

<script>

  import moment from 'moment'
  import YchSelectDepart from '@/components/ych/ych-org/YchSelectDepart'
  import YchSelectUser from '@/components/ych/ych-user/YchSelectUser'
  import {ajaxGetSqlConfigItems, ajaxGetHttpConfigItems} from '@/api/api';
  import RangeNumber from './RangeNumber'
  import pinyin from 'js-pinyin'

  export default {
    name: 'QueryField',
    components: {
      YchSelectDepart,
      YchSelectUser,
      RangeNumber,
    },
    props: {
      type: String,
      placeholder: String,
      value: String,
      showConfig: Object,
      dictOptions: Object,
      dictOptionsFlg: Number,
      linkageMap: {
        type: Object,
        default: () => {
        }
      },
    },
    data () {
      return {
        optionsResult: this.showConfig.options || [],
        syncNum: 0, // 防止异步
        options: this.showConfig.options || [],
        formatExpr: this.showConfig.formatExpr,
        min: typeof this.showConfig.min == 'undefined' ? 0 : this.showConfig.min,
        max: typeof this.showConfig.max == 'undefined' ? 999999999 : this.showConfig.max,
        step: typeof this.showConfig.step == 'undefined' ? 1 : this.showConfig.step,
        timeFormat: this.showConfig.format || 'HH:mm:ss',
        dateFormat: this.showConfig.format || 'YYYY-MM-DD',
        rangeNumberPlaceholder: [this.$t('m.common.label.begin_number'), this.$t('m.common.label.end_number')],
        rangePlaceholder: [this.$t('m.common.label.begin_time'), this.$t('m.common.label.end_time')],
        multiple: !!this.showConfig.multiple,
        useCode: !!this.showConfig.useCode,
        customOrgOrderSql: this.showConfig.customOrgOrderSql,
        customOrgFilterSql: this.showConfig.customOrgFilterSql,
        clearable: this.showConfig.clearable,
        linkage: this.showConfig.linkage,
      }
    },
    computed: {
      getValue () {
        if (this.type == "select" && this.multiple) {
          return this.value ? this.value.split(",") : [];
        } else
        if (this.type == 'number') {
          if (this.showConfig.rangeNumber) {
            return this.value ? JSON.parse(this.value).map(item => item === '' ? null : Number(item)) : undefined
          } else {
            return this.value ? Number(this.value) : null
          }
        } else if (this.type == 'time') {
          return this.value ? moment(this.value, 'HH:mm:ss') : undefined
        } else if (this.type == 'date') {
          if (this.showConfig.range) {
            return this.value ? JSON.parse(this.value).map(item => moment(item, 'YYYY-MM-DD HH:mm:ss')) : undefined
          } else {
            return this.value ? moment(this.value, 'YYYY-MM-DD HH:mm:ss') : undefined
          }
        } else if (this.type == 'switch') {
          return this.value === 'true'
        } else {
          return this.value || undefined
        }
      },
      linkageValue() {
        if (this.linkage && this.linkageMap) {
          const result = {}
          let hasValue = false
          this.linkage.split(",").forEach(key => {
            result[key] = this.linkageMap[key]
            if (result[key] !== undefined && result[key] !== null && result[key] !== "") {
              hasValue = true
            }
          })
          return hasValue ? result : null
        }
        return null
      }
    },
    watch: {
      dictOptionsFlg: {
        handler (value) {
          if (this.type !== 'select' || this.options.length > 0) {
            return
          }
          if (this.showConfig.dictOption && this.showConfig.dictOption.dictCode) {
            this.optionsResult = this.dictOptions[this.showConfig.dictOption.dictCode]
            this.formatOptionsByExpr()
          } else if(this.showConfig.sqlConfig && this.showConfig.sqlConfig.sqlCode){
            this.updateBySqlCode()
          } else if(this.showConfig.httpConfig && this.showConfig.httpConfig.httpCode){
            this.updateByHttpCode()
          }
        },
        immediate: true
      },
      linkageValue: {
        handler(newValue, oldValue) {
          if (this.type !== 'select' || this.options.length > 0) {
            return
          }
          if (JSON.stringify(newValue || {}) === JSON.stringify(oldValue || {})) {
            return
          }
          if (this.showConfig.dictOption && this.showConfig.dictOption.dictCode) {
          } else if (this.showConfig.sqlConfig && this.showConfig.sqlConfig.sqlCode) {
            this.updateBySqlCode()

            if (oldValue) {
              // 清空选项
              this.$emit('input', null)
              this.$emit('change', null)

              // 联动
              this.$emit('setLinkageMap', null)
            }
          } else if (this.showConfig.httpConfig && this.showConfig.httpConfig.httpCode) {
            this.updateByHttpCode()

            if (oldValue) {
              // 清空选项
              this.$emit('input', null)
              this.$emit('change', null)

              // 联动
              this.$emit('setLinkageMap', null)
            }
          }
        }
      }
    },
    created() {
      if(this.optionsResult.length > 0){
        this.formatOptionsByExpr()
      }
    },
    methods: {
      updateBySqlCode(){
        const parameter = {}
        if (this.linkage && this.linkageValue) {
          Object.assign(parameter, this.linkageValue)
        } else if(this.linkage){
          // 如果要空值查询，需要放开这里
          this.optionsResult = []
          return;
        }

        // 入参
        if (this.showConfig.sqlConfig.sqlParameterConfig && this.showConfig.sqlConfig.sqlParameterConfig.length > 0) {
          this.showConfig.sqlConfig.sqlParameterConfig.forEach(item => {
            let value = null;
            if (item.defaultValue) {
              value = item.defaultValue
            }
            if (value) {
              parameter[item.parameterKey] = value
            }
          })
        }

        this.syncNum ++
        const syncNum = this.syncNum
        ajaxGetSqlConfigItems(this.showConfig.sqlConfig.sqlCode, parameter).then((res) => {
          // 防止异步
          if(syncNum !== this.syncNum){
            return;
          }
          if (res.success) {
            this.optionsResult = res.result;
            this.formatOptionsByExpr()
          }
        })
      },
      updateByHttpCode(){
        const parameter = {}
        if (this.linkage && this.linkageValue) {
          Object.assign(parameter, this.linkageValue)
        } else if(this.linkage){
          this.optionsResult = []
          return;
        }
        this.syncNum ++
        const syncNum = this.syncNum
        parameter.httpConfig = this.showConfig.httpConfig
        ajaxGetHttpConfigItems(this.showConfig.httpConfig.httpCode, parameter).then((res) => {
          // 防止异步
          if(syncNum !== this.syncNum){
            return;
          }
          if (res.success) {
            this.optionsResult = res.result;
            this.formatOptionsByExpr()
          }
        })
      },
      formatOptionsByExpr() {
        if (!this.formatExpr) {
          return;
        }
        this.optionsResult = JSON.parse(JSON.stringify(this.optionsResult))
        this.optionsResult.forEach(item => {
          let value = item.text || item.label
          let key = item.value
          if (value) {
            const text = this.formatExpr.replace(/\$\{key\}/g, !key ? "" : key).replace(/\$\{value\}/g, !value ? "" : value);
            item.text = text
            item.label = text
          }
        })
      },
      onChange (val, timeString) {
        let data
        if (this.type == "select" && this.multiple) {
          data = val.join(",");
        } else
        if (this.type == 'number') {
          if (this.showConfig.rangeNumber) {
            data = (val && val.length > 0) ? JSON.stringify(val.map(item => item || item === 0 ? item : '')) : undefined
          } else {
            data = (val || val === 0) ? val + '' : null
          }
        } else if (this.type == 'time') {
          data = val ? (moment(timeString, this.timeFormat).format('HH:mm:ss')) : ''
        } else if (this.type == 'date') {
          if (this.showConfig.range) {
            data = (val && val.length > 0) ? JSON.stringify(timeString.map((item, index) => {
              const oldDate = moment(item, this.dateFormat);
              if(index === 1){
                if (this.dateFormat.indexOf('MM') === -1) {
                  oldDate.endOf("year")
                } else if (this.dateFormat.indexOf('DD') === -1) {
                  oldDate.endOf("month")
                } else if (this.dateFormat.indexOf('HH') === -1) {
                  oldDate.endOf("day")
                } else if (this.dateFormat.indexOf('mm') === -1) {
                  oldDate.endOf("hour")
                } else if (this.dateFormat.indexOf('ss') === -1) {
                  oldDate.endOf("minute")
                }
              } else {

              }
              return oldDate.format('YYYY-MM-DD HH:mm:ss');
            })) : undefined
          } else {
            data = val ? (moment(timeString, this.dateFormat).format('YYYY-MM-DD HH:mm:ss')) : ''
          }
        } else {
          data = val
        }

        this.$emit('input', data)
        this.$emit('change', data)

        // 联动
        this.$emit('setLinkageMap', data)
      },
      onChangeSwitch (checked) {
        this.$emit('input', checked + '')
        this.$emit('change', checked + '')

        // 联动
        this.$emit('setLinkageMap', checked + '')
      },
      onChangeInput (e) {
        let val = e.target.value
        this.$emit('input', val)
        this.$emit('change', val)

        // 可能是清空触发的变动，无法执行onblur，在这里执行
        if (!val) {
          // 联动
          this.$emit('setLinkageMap', val)
        }
      },
      onChangeBlur (e) {
        let val = e.target.value

        // 联动
        this.$emit('setLinkageMap', val)
      },
      filterOption(input, option) {
        let optionValue = option.componentOptions.children[0].text
        let jp = pinyin.getCamelChars(optionValue)
        if(!jp){
          jp = ''
        }
        if(optionValue.toLowerCase().indexOf(input.toLowerCase()) >= 0
          || jp.toLowerCase().indexOf(input.toLowerCase())>=0){
          return true
        }else{
          return false
        }
      },
    }
  }
</script>
